'''
Created on Oct 11, 2011

@author: Nam Khanh Tran
'''

import os
import re
import sys 

from angluin.constant import TEST_FOLDER, TEST_RESULT
from angluin.fsa import FSA

logger = open('log.txt', 'w')
acceptor = FSA()
confused_set = dict()

def parse(sense, subj, verb, obj, prep):
       
    examples = set()
#    print subj
#    print verb
#    print obj
#    print prep
    valid = 0
    invalid = 0
    g_sense = set()

    for v in verb:
        if len(subj) > 0:
            for s in subj:
                if len(obj) > 0:
                    for o in obj:
                        if len(prep) > 0:
                            for p in prep:
                                inst = "%s %s %s %s"  % (s,v,o,p)
                                if acceptor.parse(inst):
                                    g_sense.add(v)
                                    if v == sense: valid = valid + 1
                                    else: invalid = invalid + 1
                                    examples.add(inst)
                        else:
                            inst = "%s %s %s" % (s,v,o)
                            if acceptor.parse(inst):
                                g_sense.add(v)
                                if v == sense: valid = valid + 1
                                else: invalid = invalid + 1
                                examples.add(inst)                            
                else:
                    inst = "%s %s" % (s,v)
                    if acceptor.parse(inst):
                        g_sense.add(v)
                        if v == sense: valid = valid + 1
                        else: invalid = invalid + 1
                        examples.add(inst)
                    
        if len(obj) > 0:
            for o in obj:
                if len(prep) > 0:
                    for p in prep:
                        inst = "%s %s %s" % (v,o,p)
                        if acceptor.parse(inst):
                            g_sense.add(v)
                            if v == sense: valid = valid + 1
                            else: invalid = invalid + 1
                            examples.add(inst)
                else:
                    inst = "%s %s" % (v,o)
                    if acceptor.parse(inst):
                        g_sense.add(v)
                        if v == sense: valid = valid + 1
                        else: invalid = invalid + 1
                        examples.add(inst)
        if len(prep) > 0:
            for p in prep:
                inst = "%s %s" % (v,p)
                if acceptor.parse(inst):
                    g_sense.add(v)
                    if v == sense: valid = valid + 1
                    else: invalid = invalid + 1
                    examples.add(inst)
    
#    print examples
    
    return (valid, invalid, g_sense)
    
def wsd(sense, fname):
    
    print fname    
    
    fin = open(fname, 'r')
    correct= 0
    incorrect = 0
    ambiguity = 0
    unpredictable = 0
    total = 0
    try:
        lines = fin.read().split('\n')
        total = len(lines)
        for sent in lines:
            comp = re.split('\t', sent)
            sent_id = comp[0]
            subj = list()
            verb = list()
            obj = list()
            prep = list()

            for e in comp[1:]:
                if len(e) == 0: continue
                if e.find('s') == 1:
                    for s in re.split(',', e[1:len(e)-1]):
                        subj.append(s)
                if e.find('v') == 1:
                    for v in re.split(',', e[1:len(e)-1]):
                        verb.append(v)
                if e.find('o') == 1:
                    for o in re.split(',', e[1:len(e)-1]):
                        obj.append(o)
                if e.find('p') == 1:
                    for p in re.split(',', e[1:len(e)-1]):
                        prep.append(p)
            if len(subj) == 0 and len(obj) == 0 and len(prep) == 0:
                logger.write(sent_id + '\n')
            else:
#                print sent_id
                (valid, invalid, g_sense) = parse(sense, subj, verb, obj, prep)
                if valid == 0 and invalid == 0:
                    unpredictable = unpredictable + 1
                if valid > 0 and invalid == 0:
                    correct = correct + 1
                if valid == 0 and invalid > 0 and len(g_sense) == 1:
                    incorrect = incorrect + 1
                if invalid > 0 and len(g_sense) > 1:
                    ambiguity = ambiguity + 1
                    
        return (correct, incorrect, unpredictable, ambiguity, 
                    total-(correct+incorrect+unpredictable+ambiguity))
    finally:
        fin.close()

def test(verb):
    """
    Test for all the files of the verb in the test folder 
    """
    acceptor.init(verb)
    fout = open(TEST_RESULT + verb, 'w')
    correct_examples = 0
    incorrect_examples = 0
    total_examples = 0 
    unpredictable_examples = 0
    ambiguous_examples = 0
    number_sense = 0  
    for fname in os.listdir(TEST_FOLDER):
        if fname.find(verb) != -1:
            pos = fname.find('doc.')
            sense = 'v' + fname[pos+4:fname.find('.complete')]
            number_sense = number_sense + 1
            logger.write(fname + '\n')
            (correct, incorrect, unpredictable, ambiguity, 
                        incomplete_input) =  wsd(sense, TEST_FOLDER + '/' + fname)
            if correct == 0:
                p = 0.0
            else: 
                p = (correct * 1.0/(correct+incorrect))
            r = (correct * 1.0/(correct+incorrect+unpredictable+ambiguity+incomplete_input))
            fout.write("Sense = %s\n" % (sense))
            fout.write("Precision = %.2f\n" % (p))
            fout.write("Recall = %.2f\n" % (r))
            correct_examples = correct_examples + correct
            incorrect_examples = incorrect_examples + incorrect
            unpredictable_examples = unpredictable_examples + unpredictable
            ambiguous_examples = ambiguous_examples + ambiguity
            total_examples = total_examples + correct+incorrect+unpredictable+ambiguity+incomplete_input
    
    avgP = correct_examples*1.0/(correct_examples+incorrect_examples)
    avgR = correct_examples*1.0/total_examples
    fout.write("\nVerb Precision = %.2f\n" % (correct_examples*1.0/(correct_examples+incorrect_examples)))
    fout.write("Average Recall = %.2f\n" % (correct_examples*1.0/total_examples))
    fout.write("F1 = %.2f\n" % (2 * avgP * avgR / (avgP + avgR)))
    fout.write("Unpredictable Examples = %.2f\n" % (unpredictable_examples*1.0/total_examples))
    fout.write("Ambiguous Examples = %.2f\n" % (ambiguous_examples*1.0/total_examples))
    fout.write("Incomplete Input = %.2f\n" % (incomplete_input*1.0/total_examples))
    fout.close()
if __name__ == "__main__":
#    if len(sys.argv) < 2:
#        print "\nUsage: python vsd.py [verb]"
#        sys.exit(1)
    
    test("yield")